{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "75e2ef28-594f-4c18-9d22-c6b8cd40ead2",
   "metadata": {},
   "source": [
    "# 📘 StudyMate – Your AI Study Assistant\n",
    "\n",
    "**StudyMate** is an AI-powered study assistant built to make learning easier, faster, and more personalized. Whether you're preparing for exams, reviewing class materials, or exploring a tough concept, StudyMate acts like a smart tutor in your pocket. It explains topics in simple terms, summarizes long readings, and even quizzes you — all in a friendly, interactive way tailored to your level. Perfect for high school, college, or self-learners who want to study smarter, not harder."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db08b247-7048-41d3-bc3b-fd4f3a3bf8cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "#install necessary dependency\n",
    "!pip install PyPDF2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "70e39cd8-ec79-4e3e-9c26-5659d42d0861",
   "metadata": {},
   "outputs": [],
   "source": [
    "# imports\n",
    "\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from google import genai\n",
    "from google.genai import types\n",
    "import PyPDF2\n",
    "from openai import OpenAI\n",
    "import gradio as gr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "231605aa-fccb-447e-89cf-8b187444536a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load environment variables in a file called .env\n",
    "# Print the key prefixes to help with any debugging\n",
    "\n",
    "load_dotenv(override=True)\n",
    "gemini_api_key = os.getenv('GEMINI_API_KEY')\n",
    "\n",
    "if gemini_api_key:\n",
    "    print(f\"Gemini API Key exists and begins {gemini_api_key[:8]}\")\n",
    "else:\n",
    "    print(\"Gemini API Key not set\")\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2fad9aba-1f8c-4696-a92f-6c3a0a31cdda",
   "metadata": {},
   "outputs": [],
   "source": [
    "system_message= \"\"\"You are a highly intelligent, helpful, and friendly AI Study Assistant named StudyMate.\n",
    "\n",
    "Your primary goal is to help students deeply understand academic topics, especially from textbooks, lecture notes, or PDF materials. You must explain concepts clearly, simplify complex ideas, and adapt your responses to the user's grade level and learning style.\n",
    "\n",
    "Always follow these rules:\n",
    "\n",
    "1. Break down complex concepts into **simple, digestible explanations** using analogies or examples.\n",
    "2. If the user asks for a **summary**, provide a concise yet accurate overview of the content.\n",
    "3. If asked for a **quiz**, generate 3–5 high-quality multiple-choice or short-answer questions.\n",
    "4. If the user uploads or references a **textbook**, **PDF**, or **paragraph**, use only that context and avoid adding unrelated info.\n",
    "5. Be interactive. If a user seems confused or asks for clarification, ask helpful guiding questions.\n",
    "6. Use friendly and motivational tone, but stay focused and to-the-point.\n",
    "7. Include definitions, bullet points, tables, or emojis when helpful, but avoid unnecessary fluff.\n",
    "8. If you don't know the answer confidently, say so and recommend a way to find it.\n",
    "\n",
    "Example roles you may play:\n",
    "- Explain like a teacher 👩‍🏫\n",
    "- Summarize like a scholar 📚\n",
    "- Quiz like an examiner 🧠\n",
    "- Motivate like a friend 💪\n",
    "\n",
    "Always ask, at the end:  \n",
    "*\"Would you like me to quiz you, explain another part, or give study tips on this?\"*\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6541d58e-2297-4de1-b1f7-77da1b98b8bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize\n",
    "\n",
    "class StudyAssistant:\n",
    "    def __init__(self,api_key):\n",
    "        gemini= genai.Client(\n",
    "           api_key= gemini_api_key\n",
    "        )\n",
    "        self.gemini = gemini.chats.create(\n",
    "             model=\"gemini-2.5-flash\",\n",
    "            config= types.GenerateContentConfig(\n",
    "                system_instruction= system_message,\n",
    "                temperature = 0.7\n",
    "            )\n",
    "        )\n",
    "\n",
    "        self.ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\n",
    "        self.models = {\"llma\":\"llama3:8b\",\"qwen\":\"qwen2.5:latest\"}\n",
    "\n",
    "    def pdf_extractor(self,pdf_path):\n",
    "         \"\"\"Extract text from PDF file\"\"\"\n",
    "         try:\n",
    "            with open(pdf_path, 'rb') as file:\n",
    "                pdf_reader = PyPDF2.PdfReader(file)\n",
    "                text = \"\"\n",
    "                for page in pdf_reader.pages:\n",
    "                    text += page.extract_text() + \"\\n\"\n",
    "                return text.strip()\n",
    "         except Exception as e:\n",
    "            return f\"Error reading PDF: {str(e)}\"\n",
    "\n",
    "    def chat(self,prompt,history,model,pdf_path=None):\n",
    "        pdf_text = None\n",
    "        if pdf_path:\n",
    "            pdf_text = self.pdf_extractor(pdf_path)\n",
    "\n",
    "        #craft prompt\n",
    "        user_prompt= prompt\n",
    "        if pdf_text:\n",
    "            user_prompt += f\"\"\"Here is the study meterial:\n",
    "\n",
    "            {pdf_text}\"\"\"\n",
    "        messages = [{\"role\": \"system\", \"content\": system_message}] + history + [{\"role\": \"user\", \"content\": user_prompt}]\n",
    "\n",
    "        # call models\n",
    "        stream = []\n",
    "        if model == \"gemini\":\n",
    "            stream= self.gemini.send_message_stream(user_prompt)\n",
    "        elif model == \"llma\" or model == \"qwen\":\n",
    "            stream = self.ollama.chat.completions.create(\n",
    "                model= self.models[model],\n",
    "                messages=messages,\n",
    "                temperature = 0.7,\n",
    "                stream= True\n",
    "            )\n",
    "        else:\n",
    "            print(\"invalid model\")\n",
    "            return\n",
    "\n",
    "        res = \"\"\n",
    "        for chunk in stream:\n",
    "            if model == \"gemini\":\n",
    "                res += chunk.text or \"\"\n",
    "            else:\n",
    "                res += chunk.choices[0].delta.content or ''\n",
    "            yield res\n",
    "       "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1334422a-808f-4147-9c4c-57d63d9780d0",
   "metadata": {},
   "source": [
    "## And then enter Gradio's magic!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0866ca56-100a-44ab-8bd0-1568feaf6bf2",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "assistant = StudyAssistant(gemini_api_key)\n",
    "gr.ChatInterface(fn=assistant.chat, additional_inputs=[gr.Dropdown([\"gemini\", \"qwen\",\"llma\"], label=\"Select model\", value=\"gemini\"),gr.File(label=\"upload pdf\")], type=\"messages\").launch()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
